1001 Secrets for Windows NT Registry
(Publisher: 29th Street Press)
Author(s): Tim Daniels
ISBN: 1882419685
Publication Date: 12/01/97

Table of Contents


Appendix A
Administering The Registry

Windows NT and Windows 95 both let you administer the registry from remote locations. A simple way to change values on a system is to use Regedt32.exe to connect to a remote computer and modify the registry. This procedure works fine for small numbers of modifications or queries, but what if you have 20, 50, or 100 workstations to change?

You may decide that you want a way to automatically perform registry administration tasks on a remote computer. REGREM is a utility written in C that demonstrates remote registry administration; it queries the registry of a remote Windows NT computer. The program prints to the screen a copy of the network configuration settings for a remote Windows NT computer.

// regrem.c
// Steve Scoggins 1997

#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <ctype.h>
#include <windows.h>

#define OK ERROR_SUCCESS

main(int argc, char *argv[])
{

  static char lpszNIC_Description[80];
  static char lpszNIC_Manufacturer[80];
  static char lpszNIC_ProductName[80];
  static char lpszNIC_ServiceName[80];

  static char lpszTcpip_DefaultGateway[20];
  static char lpszTcpip_IPAddress[20];
  static char lpszTcpip_SubnetMask[20];

  static char lpszTcpip_Domain[80];
  static char lpszTcpip_Hostname[80];
  static char lpszTcpip_NameServer[80];
  static char lpszTcpip_SearchList[128];
  static char lpszComputerName[80];
  static char lpszDefaultDomainName[80];

  char szKeyPart1[] = "SYSTEM\\CurrentControlSet\\Services\\";
  char szKeyPart2[] = "\\Parameters";
  char szServiceKey[128];

  long InterruptNumber, IoBaseAddress;

  HKEY hkey, hNetKey ;
  DWORD lenKeyValue;
  unsigned long DataType;
  int err;

  char *name = argv[1];

    if ((err = RegConnectRegistry(name, HKEY_LOCAL_MACHINE, &hkey)) == OK)
    {

    // Open the Registry Key for the first instance of a Network Adapter
    // in the Registry
    // Read the Description, Manufacturer, Product Name, and Service Name
    // for this instance of an installed Network Adapter.

    if(RegOpenKey(hkey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\
          NetworkCards\\1",&hNetKey) == ERROR_SUCCESS)
    {
      RegQueryValueEx(hNetKey, "Description", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "Description", 0, &DataType,(LPTSTR)
          lpszNIC_Description, &lenKeyValue);
      printf("Windows NT Network Adapter:\n");
      printf("Description: %s\n",lpszNIC_Description);

      RegQueryValueEx(hNetKey, "Manufacturer", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "Manufacturer", 0, &DataType,
          (LPTSTR)lpszNIC_Manufacturer, &lenKeyValue);
      printf("Manufacturer: %s\n",lpszNIC_Manufacturer);

      RegQueryValueEx(hNetKey, "ProductName", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "ProductName", 0, &DataType,
          (LPTSTR)lpszNIC_ProductName, &lenKeyValue);
      printf("Product Name: %s\n",lpszNIC_ProductName);

      RegQueryValueEx(hNetKey, "ServiceName", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "ServiceName", 0, &DataType,
          (LPTSTR)lpszNIC_ServiceName, &lenKeyValue);
      printf("Service Name: %s\n",lpszNIC_ServiceName);

      RegCloseKey(hNetKey);
    }

    // Now that we have the ServiceName for the Network Adapter from the
    // NetworkCards key we will reconstruct the correct ServiceKey path
    // based on the Service Name for this network adapter.

    strcpy(szServiceKey, szKeyPart1);
    strcat(szServiceKey, lpszNIC_ServiceName);
    strcat(szServiceKey, szKeyPart2);

    if(RegOpenKey(hkey, (LPCTSTR) szServiceKey, &hNetKey) == ERROR_SUCCESS)
    {

      RegQueryValueEx(hNetKey, "InterruptNumber", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "InterruptNumber", 0, &DataType, (LPBYTE)
          &InterruptNumber, &lenKeyValue);
      printf("Interrupt Number: %x\n",InterruptNumber);

      RegQueryValueEx(hNetKey, "IoBaseAddress", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "IoBaseAddress", 0, &DataType, (LPBYTE)
          &IoBaseAddress, &lenKeyValue);
      printf("IO Base Address: %x\n",IoBaseAddress);
      RegCloseKey(hNetKey);
    }

    // Open the TCP/IP Key for this Network Adapter
    // Read some of the key TCP/IP parameters for this Network Adapter

    strcat(szServiceKey, "\\Tcpip");

    if(RegOpenKey(hkey, (LPCTSTR) szServiceKey ,&hNetKey) == ERROR_SUCCESS)
    {
      RegQueryValueEx(hNetKey, "DefaultGateway", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "DefaultGateway", 0, &DataType,(LPTSTR)
          lpszTcpip_DefaultGateway, &lenKeyValue);
      printf("TCP/IP DefaultGateway : %s\n",lpszTcpip_DefaultGateway);

      RegQueryValueEx(hNetKey, "IPAddress", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "IPAddress", 0, &DataType,
          (LPTSTR)lpszTcpip_IPAddress, &lenKeyValue);
      printf("TCP/IP IPAddress : %s\n",lpszTcpip_IPAddress);

      RegQueryValueEx(hNetKey, "SubnetMask", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "SubnetMask", 0, &DataType,
          (LPTSTR)lpszTcpip_SubnetMask, &lenKeyValue);
      printf("TCP/IP Subnet Mask : %s\n",lpszTcpip_SubnetMask);
      RegCloseKey(hNetKey);
    }

    // Read the global TCP/IP paramters

    if(RegOpenKey(hkey, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\
          Parameters",&hNetKey) == ERROR_SUCCESS)
    {
      RegQueryValueEx(hNetKey, "Domain", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "Domain", 0, &DataType,
          (LPTSTR)lpszTcpip_Domain, &lenKeyValue);
      printf("TCP/IP Domain Name: %s\n",lpszTcpip_Domain);

      RegQueryValueEx(hNetKey, "Hostname", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "Hostname", 0, &DataType,
          (LPTSTR)lpszTcpip_Hostname, &lenKeyValue);
      printf("TCP/IP Hostname: %s\n",lpszTcpip_Hostname);

      RegQueryValueEx(hNetKey, "NameServer", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "NameServer", 0, &DataType,
          (LPTSTR)lpszTcpip_NameServer, &lenKeyValue);
      printf("TCP/IP DNS Name Servers: %s\n",lpszTcpip_NameServer);

      RegQueryValueEx(hNetKey, "SearchList", 0, &DataType, NULL,
          &lenKeyValue);
      RegQueryValueEx(hNetKey, "SearchList", 0, &DataType,
          (LPTSTR)lpszTcpip_SearchList, &lenKeyValue);
      printf("TCP/IP Domain Name Search List: %s\n",lpszTcpip_SearchList);

      RegCloseKey(hNetKey);
    }

    // Read the Computer Name and Domain Name for this Windows NT Computer

    if(RegOpenKey(hkey, "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\
          ActiveComputerName", &hNetKey) == ERROR_SUCCESS)
    {
      RegQueryValueEx(hNetKey, "ComputerName", 0, &DataType,
          NULL, &lenKeyValue);
      RegQueryValueEx(hNetKey, "ComputerName", 0, &DataType,
          (LPTSTR)lpszComputerName, &lenKeyValue);
      printf("Windows NT Computer Name: %s\n",lpszComputerName);

      RegCloseKey(hNetKey);
    }

    if(RegOpenKey(hkey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\
          Winlogon", &hNetKey) == ERROR_SUCCESS)
    {
      RegQueryValueEx(hNetKey, "DefaultDomainName", 0, &DataType,
          NULL, &lenKeyValue);
      RegQueryValueEx(hNetKey, "DefaultDomainName", 0, &DataType,
          (LPTSTR)lpszDefaultDomainName, &lenKeyValue);
      printf("Windows NT DomainName: %s\n",lpszDefaultDomainName);

      RegCloseKey(hNetKey);
    }
    RegCloseKey(hkey);
    }

    else
    {
        switch (err)
        {
            #define MSG(x) case x : printf("%s\t\t\t\n", #x)
            MSG(ERROR_OPERATION_ABORTED); break;
            MSG(ERROR_BAD_NETPATH); break;
            MSG(ERROR_ACCESS_DENIED); break;
            default: printf("Error #%u (look in WINERROR.H)\n", err);
            break;
        }
        printf("failed to connect to remote registry");
    }
    printf("bye!\n");
    return 0;
}

The source and the compiled executable are available on the CD-ROM that comes with this book. To run REGREM, you must be logged on as an administrator of the Windows NT Domain for the remote computer.

A network administrator could use this type of software utility to query the network configuration for all the Windows NT computers on the local network. The results are printed to the screen. If you want a file containing this information, you can redirect the screen printout to a file using the following form of the command:

REGREM ComputerName > FileName

Sample output from REGREM is shown below.

Windows NT Network Adapter:
Description: 3Com Etherlink III PCI Bus-Master Adapter (3C590)
Manufacturer: 3Com
Product Name: El59x
Service Name: El59x1
Interrupt Number: 12ff8c
IO Base Address: 3
TCP/IP DefaultGateway : 200.200.200.254
TCP/IP IPAddress : 200.200.200.200
TCP/IP Subnet Mask : 255.255.255.0
TCP/IP Domain Name: test.com
TCP/IP Hostname: bigdog
TCP/IP DNS Name Servers:
TCP/IP Domain Name Search List:
Windows NT Computer Name: BIGDOG
Windows NT DomainName: BIGDOG
bye!

You can also run the Regrem.exe client on any Windows 95 or Windows NT workstation that is logged on to your Windows NT Domain. To run this utility on a Windows 95 computer, install the Microsoft Remote Registry Services. The REGREM client utility uses Winreg.dll as an RPC client that communicates with the RPC server on the remote Windows NT computer. The RPC service on the remote computer uses Regserv.exe.

You must enable user-level access before you can run remote registry software on a Windows 95 computer. You also must be authenticated by the Windows NT Domain server before you are allowed to connect to a remote registry on a Windows NT computer in the Windows NT Domain.

Installing Remote Registry Services on a Windows 95 Computer

1.  Open My Computer.
2.  Open Control Panel.
3.  Open the Network applet.
4.  Click Add.
5.  Double-click Service.
6.  Click Have Disk.
7.  When the install dialog box opens, type Admin\NetTools\RemoteReg for the directory path.
8.  Click OK.
9.  When the network service dialog box opens, select the Microsoft Remote Registry service.
10.  Click OK.
11.  Click the Access Control Tab in the Network setup dialog box.
12.  Check the “User-level access control” option.
13.  Click OK.
14.  Type your Windows NT Domain name in the “Obtain list of users and groups from” box and click OK.

Enabling Remote Administration for a Windows 95 Computer

Note: for remote registry administration to work, you must enable remote registration on the remote Windows 95 computers.

1.  Open My Computer.
2.  Open the Control Panel.
3.  Open the Passwords applet.
4.  Click the Remote Administration tab.
5.  Check “Enable Remote Administration of this server.”
6.  The Domain Administrators are listed in the list box of users allowed to use Remote Administration. Click the Add button to add other NT Domain users authorized to use Remote Administration.
7.  Click OK to finish.

This program is meant as a demonstration of what is possible. Make sure you visit this book’s Web site frequently for updates and other programming examples.

Using Windows 95-Style INF Files to Modify Registry Settings

Another way to modify the Windows NT registry automatically without writing code is to use .inf files. You can change multiple workstations and servers remotely and automatically. To avoid having to fire up Regedt32.exe for each change, you can simply tell the Logon.bat file to run your .inf file, which can perform any sort command or registry modification.

The following command line runs an .inf file on a Windows NT computer:

RUNDLL32 syssetup,SetupInfObjectInstallAction DefaultInstall 128 E:\NT
Registry\cdautoff.inf

It is very important that you provide the fully qualified path to the .inf file. If you just supply the filename, this procedure will not work. You can place this command line in a logon batch file if you want to make this modification for multiple users. You can then edit the users’ profiles and specify this batch file.

Listed below is an INF file that turns off CD-ROM Autorun via the registry.

; CDAUTOFF.INF
;
; This is an example INF setup information file to turn OFF CD-ROM Autorun

[Version]
Signature="$Windows NT$"
Provider=%Provider%

[Strings]
Provider="Steve Scoggins"

[DefaultInstall]
AddReg = add.reg

[add.reg]
HKLM,SYSTEM\CurrentControlSet\Services\Cdrom,"Autorun",0x10001,0

You can automatically roll out any number of modifications to the registry using this technique. The trick is learning what the bit fields for each key does.

For more information about using INF files to automate installing applications or making registry changes, I recommend the references cited below:

  Microsoft Windows NT Workstation Resource Kit, Microsoft Press ISBN 1-57231-343-9, Chapter 2, Customizing Setup; “Creating .inf files”, page 59
  Microsoft Visual C++ 5.0 Professional Edition, Microsoft Developer Studio Infoviewer


Table of Contents